"""
    @File        : services.py
    @Author      : 狡猾的皮球
    @Date        : 2020/8/28 23:04
    @QQ          : 871245007
    @Description :
        创建账号的一些操作
"""
import random

from commons.models import Player


class Fighter:
    """
    战斗者
    """

    def __init__(self, name, hp, mp, atk, ac, speed, hit, dodge, crit, rcrit, counter, rcounter, leech, atk_level,
                 ac_level):
        """
        构造战斗者
        """
        self.name = name

        # 基础属性
        self.hp = [hp, hp]
        self.mp = [mp, mp]
        self.atk = atk
        self.ac = ac
        self.speed = speed

        # 高阶属性
        self.hit = hit  # 命中
        self.dodge = dodge  # 闪避
        self.crit = crit  # 暴击
        self.rcrit = rcrit  # 抗暴击
        self.counter = counter  # 反击
        self.rcounter = rcounter  # 抗反击
        self.leech = leech  # 吸血，单位百分之0.01

        # 修炼等级
        self.atk_level = atk_level  # 攻击修炼
        self.ac_level = ac_level  # 防御修炼

    def attack_handler(self, target):
        """
        完整的攻击反击逻辑处理
        :param target: 敌人
        :return:
        {
            "is_hit":True, # 是否命中
            "is_crit": True, # 是否暴击
            "damage": 100, # 伤害
            "leech_amount":0, # 吸血量
            # 反击，如果没有反击该值就为null
            "counter":{
                "is_hit":True, # 是否命中
                "is_crit": True, # 是否暴击
                "damage": 100, # 伤害
                "leech_amount":0, # 吸血量
            }
        }
        """
        result = self.attack(target)
        counter_result = None
        if target.counter > 0:
            counter_range = int(10000 * target.counter / (target.counter + self.rcounter))
            is_counter = random.randint(1, 10000) <= counter_range
        else:
            is_counter = False
        if target.hp[0] > 0 and is_counter:
            # 反击逻辑
            counter_result = target.attack(self)
        result["counter"] = counter_result
        return result

    def attack(self, target):
        """
        伤害计算公式：
            我方攻击>=目标防御
                总伤害 = (我方攻击-目标防御)*(1+0.02*攻击修炼等级)+修炼等级*5
                最终伤害 = 总伤害-总伤害*0.02*对方防御修炼等级-对方防御修炼等级*5
                最终伤害最小值为1
            我方攻击<目标防御
                总伤害 = 修炼等级*5
                最终伤害 = 总伤害-总伤害*0.02*对方防御修炼等级-对方防御修炼等级*5
                最终伤害最小值为1

        普通攻击，返回：
        {
            "is_hit":True, # 是否命中
            "is_crit": True, # 是否暴击
            "damage": 100, # 伤害
            "leech_amount":0, # 吸血量
        }
        """
        result = {
            "is_hit": True,  # 是否命中
            "is_crit": True,  # 是否暴击
            "damage": 0,  # 伤害
            "leech_amount": 0,  # 吸血量
        }
        # 计算是否命中
        if self.hit > 0:
            hit_range = int(10000 * self.hit / (self.hit + target.dodge))
            is_hit = random.randint(1, 10000) <= hit_range
        else:
            is_hit = False
        result["is_hit"] = is_hit
        # 计算是否暴击
        if self.crit > 0:
            crit_range = int(10000 * self.crit / (self.crit + target.rcrit))
            is_crit = random.randint(1, 10000) <= crit_range
        else:
            is_crit = False
        result["is_crit"] = is_crit
        # 计算伤害
        if not is_hit:
            final_damage = 0
        else:
            final_damage = self.calc_damage(self.atk, self.atk_level, target.ac, target.ac_level)
            if is_crit:
                final_damage *= 2
            result["damage"] = final_damage
        # 敌人扣血
        target.hp[0] -= final_damage
        # 吸血
        leech_amount = int(final_damage * self.leech / 10000)
        self.hp[0] += leech_amount
        if self.hp[0] > self.hp[1]:
            self.hp[0] = self.hp[1]
        return result

    def calc_damage(self, atk, atk_level, ac, ac_level):
        """
        计算普通攻击伤害
        """
        delta = atk - ac
        if delta < 0:
            delta = 0
        total_damage = delta * (1 + 0.02 * atk_level) + atk_level * 5
        final_damage = total_damage - total_damage * 0.02 * ac_level - 5 * ac_level
        final_damage = int(final_damage)
        if final_damage <= 0:
            final_damage = 1
        return final_damage


f1 = Fighter("狡猾的皮球", hp=100, mp=100, atk=10, ac=10, speed=10, hit=20, dodge=0, crit=1000, rcrit=90, counter=0,
             rcounter=0, leech=0, atk_level=10, ac_level=0)

f2 = Fighter("拜月教主", hp=100, mp=100, atk=10, ac=10, speed=10, hit=10, dodge=10, crit=10, rcrit=90, counter=1,
             rcounter=0, leech=0, atk_level=10, ac_level=0)

print(f1.attack_handler(f2))
